﻿using Levfier.GUI.EditorControls.Parameters;
using Levfier.Proccessors.Parameters;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Threading;

namespace Levfier.GUI.EditorControls.Measuring
{
    /// <summary>
    /// SpectrumAnalyzerWindow.xaml の相互作用ロジック
    /// </summary>
    [Serializable]
    public partial class SpectrumAnalyzerWindow : Window
    {
        /// <summary>
        /// パラメータテーブル
        /// </summary>
        private IDictionary<string, ProccessParameter> parameters;

        /// <summary>
        /// タイマー
        /// </summary>
        private DispatcherTimer dispatcherTimer;

        /// <summary>
        /// ビットマップ描画クラスのリスト
        /// </summary>
        private IBitmapDrawable bitmapDrawer;

        /// <summary>
        /// 移動の中心
        /// </summary>
        private int moveBaseAxix;

        /// <summary>
        /// 移動フラグ
        /// </summary>
        private bool moveFlag;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="drawer">スペクトル描画するクラス</param>
        /// <param name="parameters">パラメータテーブル</param>
        public SpectrumAnalyzerWindow(IBitmapDrawable drawer, IDictionary<string, ProccessParameter> parameters)
        {
            InitializeComponent();

            this.parameters = parameters;
            this.bitmapDrawer = drawer;

            this.spectrumImage.Source = drawer.CreateBitmap();

            this.stack.Children.Insert(2, new ProccessorPropertyEditorView(this.parameters));

            ////使われていないパラメータをスライダとして登録する
            //foreach (ProccessParameter param in parameters.Values)
            //{
            //    if (!param.IsUsed)
            //    {
            //        //パラメータを画面に登録
            //        this.RegisterSlider(param);
            //    }
            //}

            this.dispatcherTimer = new DispatcherTimer(DispatcherPriority.Render);
            this.dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 50);
            this.dispatcherTimer.Tick += Analyzer_UpdateNotify;
            this.dispatcherTimer.Start();
        }

        /// <summary>
        /// 画面を更新する
        /// </summary>
        private void Analyzer_UpdateNotify(object sender, EventArgs e)
        {
            if (Visibility.Visible == this.Visibility)
            {
                this.bitmapDrawer.Update(this.mode.SelectedIndex, this.powerMode.SelectedIndex);
            }
        }

        ///// <summary>
        ///// パラメータをスライダとしてスタックに登録する
        ///// </summary>
        ///// <param name="parameter">スライダにするパラメータ</param>
        //private void RegisterSlider(ProccessParameter parameter)
        //{
        //    if (ParameterType.Bool == parameter.Type)
        //    {
        //        ParameterSwitch paramSwitch = new ParameterSwitch();
        //        paramSwitch.ValueChanged += this.Switch_ValueChanged;
        //        paramSwitch.parameterName.Text = parameter.Name;
        //        this.parameterStack.Children.Add(paramSwitch);
        //    }
        //    else if (ParameterType.Value == parameter.Type)
        //    {
        //        ParameterSlider slider = new ParameterSlider();
        //        slider.parameterSlider.Maximum = parameter.MaxValue;
        //        slider.parameterSlider.Minimum = parameter.MinValue;
        //        slider.parameterSlider.Value = parameter.Value;
        //        slider.parameterSlider.SmallChange = parameter.Step;
        //        slider.ValueChanged += this.Slider_ValueChanged;
        //        slider.parameterName.Text = parameter.Name;
        //        this.parameterStack.Children.Add(slider);
        //    }
        //}

        ///// <summary>
        ///// スライダの値が変更された時の動作
        ///// </summary>
        ///// <param name="sender">イベント発生源</param>
        ///// <param name="e">イベント</param>
        //private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        //{
        //    ParameterSlider slider = sender as ParameterSlider;

        //    //更新されたスライダを元に、同じ名前のパラメータを全て更新する
        //    ProccessParameter param = this.parameters[slider.parameterName.Text];

        //    param.Value = slider.parameterSlider.Value;
        //}

        //// <summary>
        ///// スイッチの値が変更された時の動作
        ///// </summary>
        ///// <param name="sender">イベント発生源</param>
        ///// <param name="e">イベント</param>
        //private void Switch_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        //{
        //    ParameterSwitch paramSwitch = sender as ParameterSwitch;

        //    //更新されたスライダを元に、同じ名前のパラメータを全て更新する
        //    ProccessParameter param = this.parameters[paramSwitch.parameterName.Text];

        //    if ((bool)paramSwitch.parameterSwitch.IsChecked) //チェックされている場合
        //    {
        //        param.Value = 1;
        //    }
        //    else //チェックされていない場合
        //    {
        //        param.Value = 0;
        //    }
        //}

        /// <summary>
        /// マウスホイールを回した時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpectrumImage_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            this.bitmapDrawer.Zoom(e.Delta, (int)e.GetPosition(this.spectrumImage).X);
        }

        /// <summary>
        /// マウスをダウンした時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpectrumImage_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.moveBaseAxix = (int)e.GetPosition(this.spectrumImage).X;
            this.moveFlag = true;
        }

        /// <summary>
        /// マウスをアップした時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpectrumImage_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.moveFlag = false;
        }

        /// <summary>
        /// マウス移動時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpectrumImage_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            //移動中の場合
            if(this.moveFlag)
            {
                int moveAfterAxis = (int)e.GetPosition(this.spectrumImage).X;
                this.bitmapDrawer.Move(moveAfterAxis - this.moveBaseAxix);
                this.moveBaseAxix = moveAfterAxis;
            }
        }

        /// <summary>
        /// マウスが外に出た時の動作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SpectrumImage_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.moveFlag = false;
        }
    }
}
